package com.yuantu.judiciary.serviceimpl;

import com.alibaba.fastjson2.JSON;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.yuantu.judiciary.dao.IDynamicInfoDao;
import com.yuantu.judiciary.dao.IQueryEntityDao;
import com.yuantu.judiciary.dao.IQueryRecordDao;
import com.yuantu.judiciary.dao.IUserFollowDao;
import com.yuantu.judiciary.exception.enums.CheckPersonExceptionEnum;
import com.yuantu.judiciary.model.domain.DynamicInfoDO;
import com.yuantu.judiciary.model.domain.QueryEntityDO;
import com.yuantu.judiciary.model.domain.QueryRecordDO;
import com.yuantu.judiciary.model.domain.UserFollowDO;
import com.yuantu.judiciary.model.dto.EntBasicDTO;
import com.yuantu.judiciary.model.dto.SearchRecordContentDTO;
import com.yuantu.judiciary.model.enums.AuthResultType;
import com.yuantu.judiciary.model.enums.QueryType;
import com.yuantu.judiciary.model.enums.UserFollowType;
import com.yuantu.judiciary.model.form.GetQueryInfoForm;
import com.yuantu.judiciary.model.vo.PageVO;
import com.yuantu.judiciary.model.vo.UserFollowDynamicVO;
import com.yuantu.judiciary.model.vo.UserFollowEnterpriseVO;
import com.yuantu.judiciary.model.vo.UserFollowPersonVO;
import com.yuantu.judiciary.service.ICheckResultService;
import com.yuantu.judiciary.service.IUserFollowService;
import com.yuantu.judiciary.utils.AssertUtil;
import com.yuantu.judiciary.utils.PageUtil;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 用户关注
 *
 * @author syw
 * @since 2023-07-27
 **/
@Service
@RequiredArgsConstructor
public class UserFollowServiceImpl implements IUserFollowService {

    private static final Gson GSON = new Gson();
    private final IQueryRecordDao queryRecordDao;
    private final IQueryEntityDao queryEntityDao;
    private final IUserFollowDao userFollowDao;
    private final IDynamicInfoDao dynamicInfoDao;
    private final ICheckResultService checkResultService;

    @Override
    public Boolean add(Long accountId, GetQueryInfoForm form, UserFollowType type) {
        QueryRecordDO queryRecord = queryRecordDao.findByIdAndDeletedFalse(form.getId());
        AssertUtil.assertTrue(!ObjectUtils.isEmpty(queryRecord), CheckPersonExceptionEnum.QUERY_RECORD_NOT_EXIST);

        QueryEntityDO entity = checkResultService.getQueryEntity(accountId, queryRecord, JSON.parseObject(queryRecord.getContent(), SearchRecordContentDTO.class));
        UserFollowDO follow = userFollowDao.findByEntityIdAndCreatorIdAndDeletedFalse(entity.getId(), accountId);
        if (ObjectUtils.isEmpty(follow)) {
            UserFollowDO userFollow = new UserFollowDO();
            userFollow.setEntityId(entity.getId());
            userFollow.setType(type);
            userFollow.setCreatorId(accountId);
            userFollowDao.save(userFollow);
        }

        return true;
    }

    @Override
    public Boolean cancel(Long accountId, GetQueryInfoForm form) {
        QueryRecordDO queryRecord = queryRecordDao.findByIdAndDeletedFalse(form.getId());
        AssertUtil.assertTrue(!ObjectUtils.isEmpty(queryRecord), CheckPersonExceptionEnum.QUERY_RECORD_NOT_EXIST);

        UserFollowDO follow = userFollowDao.findByEntityIdAndCreatorIdAndDeletedFalse(queryRecord.getEntityId(), accountId);
        if (!ObjectUtils.isEmpty(follow)) {
            follow.setDeleted(true);
            userFollowDao.save(follow);
        }
        return true;
    }

    @Override
    public PageVO<UserFollowEnterpriseVO> getFollowEnterprisePage(Long accountId, Pageable pageable) {
        // todo 修改时需要对应数据，查询建议联合查询 我的客户和我的供应商也对应要修改
        Page<UserFollowDO> page = userFollowDao.findByCreatorIdAndTypeAndDeletedFalse(accountId, UserFollowType.ENTERPRISE, pageable);
        if (CollectionUtils.isEmpty(page.getContent())) {
            return new PageVO<>(page.getTotalElements(), Collections.emptyList());
        }
        List<Long> entityIds = page.getContent().stream()
                .filter(Objects::nonNull)
                .map(UserFollowDO::getEntityId).distinct()
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(entityIds)) {
            return new PageVO<>(page.getTotalElements(), Collections.emptyList());
        }
        Map<Long, QueryEntityDO> entityMap = queryEntityDao.findByIdInAndDeletedFalse(entityIds).stream()
                .collect(Collectors.toMap(QueryEntityDO::getId, d -> d));
        Map<Long, QueryRecordDO> queryMap = queryRecordDao.findByCreatorIdAndEntityIdInAndDeletedFalse(accountId, entityIds).stream()
                .collect(Collectors.toMap(QueryRecordDO::getEntityId, d -> d));
        if(CollectionUtils.isEmpty(queryMap)){
            return new PageVO<>(page.getTotalElements(), Collections.emptyList());
        }

        return new PageVO<>(page.getTotalElements(), page.getContent().stream().map(data -> {
            UserFollowEnterpriseVO res = new UserFollowEnterpriseVO();
            QueryRecordDO queryRecord = queryMap.get(data.getEntityId());
            QueryEntityDO queryEntity = entityMap.get(data.getEntityId());
            res.setId(queryRecord.getId());
            res.setEnterpriseName(queryEntity.getName());
            if (AuthResultType.AUTHORIZED.equals(queryRecord.getAuthorizedResult())) {
                SearchRecordContentDTO param = JSON.parseObject(queryRecord.getContent(), SearchRecordContentDTO.class);
                String companyInfoStr = checkResultService.getJsonDataProd(accountId, QueryType.ENT_BASIC, param, queryEntity);
                if (StringUtils.isNotBlank(companyInfoStr)) {
                    JsonObject totalInfo = GSON.fromJson(companyInfoStr, JsonObject.class);
                    EntBasicDTO basic = JSON.parseObject(totalInfo.get("BASIC").toString(), EntBasicDTO.class);
                    res.setStatus(basic.getENTSTATUS());
                    res.setName(basic.getFRNAME());
                    res.setEsDate(basic.getESDATE());
                    res.setRegCap(basic.getREGCAP());
                    res.setQueryResult(queryRecord.getAuthorizedResult());
                }
            }
            return res;
        }).collect(Collectors.toList()));
    }

    @Override
    public PageVO<UserFollowPersonVO> getFollowPersonPage(Long accountId, Pageable pageable) {
        Page<UserFollowDO> page = userFollowDao.findByCreatorIdAndTypeAndDeletedFalse(accountId, UserFollowType.PERSON, pageable);
        if (CollectionUtils.isEmpty(page.getContent())) {
            return new PageVO<>(page.getTotalElements(), Collections.emptyList());
        }
        List<Long> entityIds = page.getContent().stream()
                .filter(Objects::nonNull)
                .map(UserFollowDO::getEntityId).distinct()
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(entityIds)) {
            return new PageVO<>(page.getTotalElements(), Collections.emptyList());
        }
        Map<Long, String> entityMap = queryEntityDao.findByIdInAndDeletedFalse(entityIds).stream()
                .collect(Collectors.toMap(QueryEntityDO::getId, QueryEntityDO::getName));
        Map<Long, Long> queryMap = queryRecordDao.findByCreatorIdAndEntityIdInAndDeletedFalse(accountId, entityIds).stream()
                .collect(Collectors.toMap(QueryRecordDO::getEntityId, QueryRecordDO::getId, (s1, s2) -> s2));
        return new PageVO<>(page.getTotalElements(), page.getContent().stream().map(data ->
                new UserFollowPersonVO(queryMap.get(data.getEntityId()), entityMap.get(data.getEntityId()))
        ).collect(Collectors.toList()));
    }

    @Override
    public Integer getFollowCount(Long accountId) {
        return userFollowDao.countDistinctByCreatorIdAndDeletedFalse(accountId);
    }

    @Override
    public PageVO<UserFollowDynamicVO> getFollowDynamic(Long accountId, Pageable pageable) {
        List<UserFollowDO> userFollowList = userFollowDao.findByCreatorIdAndDeletedFalse(accountId);
        if (CollectionUtils.isEmpty(userFollowList)) {
            return new PageVO<>(0L, Collections.emptyList());
        }

        List<Long> entityIds = userFollowList.stream().map(UserFollowDO::getEntityId).distinct().collect(Collectors.toList());
        if (CollectionUtils.isEmpty(entityIds)) {
            return new PageVO<>(0L, Collections.emptyList());
        }

        List<DynamicInfoDO> dynamicInfoList = dynamicInfoDao.findDynamicInfoByEntityIdInAndDeletedFalse(entityIds);
        if (CollectionUtils.isEmpty(dynamicInfoList)) {
            return new PageVO<>(0L, Collections.emptyList());
        }

        Map<Long, QueryRecordDO> queryMap = queryRecordDao.findByCreatorIdAndEntityIdInAndDeletedFalse(accountId, entityIds).stream()
                .collect(Collectors.toMap(QueryRecordDO::getEntityId, d -> d));

        List<UserFollowDynamicVO> dynamicList = dynamicInfoList.stream().map(data -> {
            UserFollowDynamicVO res = new UserFollowDynamicVO();
            res.setId(queryMap.getOrDefault(data.getEntityId(), new QueryRecordDO()).getId());
            res.setName(data.getName());
            res.setTitle(data.getTitle());
            res.setContent(data.getContent());
            res.setCreateTime(data.getCreateTime());
            res.setType(data.getType());
            return res;
        }).collect(Collectors.toList());

        return new PageVO<>((long) dynamicList.size(), PageUtil.getPage(dynamicList, pageable));
    }

}
